﻿using System.IO;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesFile;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using PlanningGIS.ArcGIS.Custom;

namespace PlanningGIS.ArcGIS
{
    /// <summary>
    /// 概述：CAD 帮助类<br />
    /// </summary>
    [ComVisible(true)]
    public static class CadHelper
    {
        /// <summary>
        /// 获取cad文件中的所有图层。当文件不存在时异常
        /// </summary>
        /// <param name="fullname">cad文件所在的目录</param>
        /// <returns></returns>
        public static List<IFeatureClass> GetFeatureClasses(string fullname)
        {
            string fipath = System.IO.Path.GetDirectoryName(fullname);
            string finame = System.IO.Path.GetFileName(fullname);
            List<IFeatureClass> cadlayers = new List<IFeatureClass>();
            IWorkspaceFactory pWorkspaceFactory = new CadWorkspaceFactory() as IWorkspaceFactory;//打开CAD数据集
            IFeatureWorkspace CadWorkspace = (IFeatureWorkspace)pWorkspaceFactory.OpenFromFile(fipath, 0);
            IFeatureDataset pFeatureDataset = CadWorkspace.OpenFeatureDataset(finame);//打开一个要素集  
            //IFeaturClassContainer可以管理IFeatureDataset中的每个要素类
            IFeatureClassContainer pFeatureClassContainer = (IFeatureClassContainer)pFeatureDataset;
            //对CAD文件中的要素进行遍历处理
            for (int i = 0; i < pFeatureClassContainer.ClassCount; i++)
            {
                IFeatureClass pFeatureClass = pFeatureClassContainer.get_Class(i);
                cadlayers.Add(pFeatureClass);
            }
            return cadlayers;
        }
        
        /// <summary>
        /// 根据几何类型打开 CAD 中的要素类。当文件不存在时异常
        /// </summary>
        /// <param name="cadFileName">CAD 文件名。</param>
        /// <param name="shapeType">几何类型。</param>
        /// <returns>要素类。</returns>
        public static IFeatureClass OpenFeatureClass(string cadFileName, zjgisShapeType shapeType)
        {
            string path = System.IO.Path.GetDirectoryName(cadFileName);
            IWorkspace workspace = new CadWorkspaceFactory().OpenFromFile(path, 0);
            string fileName = System.IO.Path.GetFileName(cadFileName);
            string className = string.Format("{0}:{1}", fileName, shapeType.ToString().Replace("zjgisShape", ""));
            return (workspace as IFeatureWorkspace).OpenFeatureClass(className);
        }

        /// <summary>
        /// 根据要素类名称打开 CAD 中的要素类。当文件不存在时异常
        /// </summary>
        /// <param name="cadFileName">CAD 文件名。</param>
        /// <param name="name">要素类名称。</param>
        /// <returns>要素类。</returns>
        public static IFeatureClass OpenFeatureClass(string cadFileName, string name)
        {
            string path = System.IO.Path.GetDirectoryName(cadFileName);
            IWorkspace workspace = new CadWorkspaceFactory().OpenFromFile(path, 0);
            string fileName = System.IO.Path.GetFileName(cadFileName);
            IFeatureDataset featureDataset = (workspace as IFeatureWorkspace).OpenFeatureDataset(fileName);
            IEnumDataset enumDataset = featureDataset.Subsets;
            IDataset dataset = enumDataset.Next();
            while (dataset != null)
            {
                if (dataset.Name.Contains(name)) return dataset as IFeatureClass;
                dataset = enumDataset.Next();
            }
            return null;
        }

        /// <summary>
        /// 将整个CAD文件当作一个ICadLayer图层。
        /// </summary>
        /// <param name="cadFileName">CAD 文件名。</param>
        /// <returns>CAD 图层。</returns>
        public static ICadLayer GetCadLayer(string cadFileName)
        {
            string path = System.IO.Path.GetDirectoryName(cadFileName);
            IWorkspace workspace = new CadWorkspaceFactory().OpenFromFile(path, 0);
            string fileName = System.IO.Path.GetFileName(cadFileName);
            ICadDrawingDataset cadDrawingDataset = (workspace as ICadDrawingWorkspace).OpenCadDrawingDataset(fileName);
            ICadLayer cadLayer = new CadLayer() as ICadLayer;
            cadLayer.CadDrawingDataset = cadDrawingDataset;
            cadLayer.Name = fileName;
            return cadLayer;
        }

        /// <summary>
        /// 将整个CAD文件当作一个IGroupLayer图层。
        /// </summary>
        /// <param name="fullname">Cad文件全路径</param>
        /// <param name="noShowName">不显示的图层名称</param>
        /// <returns></returns>
        public static IGroupLayer GetGroupLayer(string fullname, string noShowName = "")
        {
            string path = System.IO.Path.GetDirectoryName(fullname);
            IWorkspace workspace = new CadWorkspaceFactory().OpenFromFile(path, 0);
            string fileName = System.IO.Path.GetFileName(fullname);
            IFeatureDataset pFeatureDataset = (workspace as IFeatureWorkspace).OpenFeatureDataset(fileName);
            IFeatureClassContainer pFeatureClassContainer = pFeatureDataset as IFeatureClassContainer;
            IEnumFeatureClass pEnumFeatureClass = pFeatureClassContainer.Classes;
            pEnumFeatureClass.Reset();
            IFeatureClass pFeatCls = pEnumFeatureClass.Next();

            IGroupLayer pGropLayer = new ESRI.ArcGIS.Carto.GroupLayer() as IGroupLayer;
            IFeatureLayer pCadFeatureLayer;
            IFeatureLayer pAnnoLyr = null;
            IFeatureLayer pPointLyr = null;
            IFeatureLayer pPolylineLyr = null;
            IFeatureLayer pPolygonLyr = null;
            while (pFeatCls != null)
            {
                if (pFeatCls.FeatureType == esriFeatureType.esriFTCoverageAnnotation)
                {
                    pCadFeatureLayer = new CadAnnotationLayer() as IFeatureLayer;
                    pCadFeatureLayer.Name = "Annotation";
                    pAnnoLyr = pCadFeatureLayer as IFeatureLayer;
                }
                else
                {
                    string lyrname = "";
                    pCadFeatureLayer = new CadFeatureLayer() as IFeatureLayer;
                    switch (pFeatCls.ShapeType)
                    {
                        case esriGeometryType.esriGeometryPoint:
                            lyrname = "Point";
                            pPointLyr = pCadFeatureLayer as IFeatureLayer;
                            break;
                        case esriGeometryType.esriGeometryPolyline:
                            lyrname = "Polyline";
                            pPolylineLyr = pCadFeatureLayer as IFeatureLayer;
                            break;
                        case esriGeometryType.esriGeometryPolygon:
                            lyrname = "Polygon";
                            pPolygonLyr = pCadFeatureLayer as IFeatureLayer;
                            break;
                        default:
                            break;
                    }
                    pCadFeatureLayer.Name = lyrname;
                }
                if (!string.IsNullOrEmpty(noShowName) && !string.IsNullOrWhiteSpace(noShowName))
                {
                    string[] wheres = noShowName.Replace(";", ",").Split(',');
                    string where = "";
                    foreach (string wi in wheres)
                    {
                        where += " Layer <> '" + wi + "' and ";
                    }
                    if (where.Trim().Length > 0) where = where.Trim().Substring(0, where.Trim().Length - 3);
                    IFeatureLayerDefinition pFeatLyrDef = pCadFeatureLayer as IFeatureLayerDefinition;
                    pFeatLyrDef.DefinitionExpression = where;
                }
                pCadFeatureLayer.FeatureClass = pFeatCls;
                pFeatCls = pEnumFeatureClass.Next();
            }
            pGropLayer.Add(pAnnoLyr);
            pGropLayer.Add(pPointLyr);
            pGropLayer.Add(pPolylineLyr);
            pGropLayer.Add(pPolygonLyr);
            pGropLayer.Name = fileName;
            pGropLayer.Expanded = false;
            return pGropLayer;
        }

    }
}
